package com.tbit.uqbike.service.business.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.tbit.uqbike.manager.exception.BaseException;
import com.tbit.uqbike.object.pojo.*;
import com.tbit.uqbike.object.pojo.dto.UpgradeDTO;
import com.tbit.uqbike.object.pojo.vo.BatchOperationMsgVO;
import com.tbit.uqbike.object.pojo.vo.UpgradeDetailVO;
import com.tbit.uqbike.object.pojo.vo.UpgradeVO;
import com.tbit.uqbike.object.value.LoginInfo;
import com.tbit.uqbike.object.view.JsonResult;
import com.tbit.common.entity.view.PageResult;
import com.tbit.common.entity.view.Result;
import com.tbit.uqbike.service.business.UpgradeService;
import com.tbit.uqbike.webmanager.dao.core.MachineDao;
import com.tbit.uqbike.webmanager.dao.core.UpgradeDao;
import com.tbit.uqbike.webmanager.dao.core.VoiceLogDao;
import com.tbit.uqbike.webmanager.dao.core.VoiceTaskDao;
import com.tbit.uqbike.webmanager.util.adaPay.AdaPayUtil;
import com.tbit.uqbike.webmanager.util.excel.ExcelUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.*;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 升级
 *
 * @author <a href="mailto:liu.haoxiang@tbit.com.cn">BUGXiang</a>
 * @version 1.0
 * @see <a href="http://adsl1.tbit.com.cn:21490/pages/viewpage.action?pageId=82182491">订单号规范</a> todo
 * @since 2024/3/15
 */
@Service
@Slf4j
public class UpgradeServiceImpl extends ServiceImpl<UpgradeDao, UpgradeMachine> implements UpgradeService {

    @Resource
    private UpgradeDao upgradeDao;
    @Resource
    private MachineDao machineDao;
    @Resource
    private VoiceTaskDao voiceTaskDao;
    @Resource
    private VoiceLogDao voiceLogDao;


    /**
     * 分页查询升级车辆列表
     *
     * @param upgradeDTO upgradeDTO
     * @return Result<PageInfo < UpgradeVO>>
     */
    @Override
    public Result<PageResult<UpgradeVO>> queryPage(UpgradeDTO upgradeDTO) {
        upgradeDTO.segmentation();
        PageInfo<UpgradeVO> pageInfo = PageHelper.startPage(upgradeDTO.getPageNumber(), upgradeDTO.getSize()).doSelectPageInfo(() -> upgradeDao.queryPage(upgradeDTO));
        for (UpgradeVO upgradeVO : pageInfo.getList()) {
            if ("5".equals(upgradeVO.getUpgradeType())){
                upgradeVO.setUpgradeType("升级中");
            }else if ("4".equals(upgradeVO.getUpgradeType())){
                upgradeVO.setUpgradeType("未升级");
            }else if ("3".equals(upgradeVO.getUpgradeType())){
                upgradeVO.setUpgradeType("升级失败");
            }else if ("2".equals(upgradeVO.getUpgradeType())){
                upgradeVO.setUpgradeType("部分成功");
            }else if ("1".equals(upgradeVO.getUpgradeType())){
                upgradeVO.setUpgradeType("升级成功");
            }
        }
        return Result.success(new PageResult<UpgradeVO>(upgradeDTO.getPageNumber(), upgradeDTO.getSize(), pageInfo.getTotal(), pageInfo.getPages(), pageInfo.getList()));
    }


    /**
     * 导入车辆
     *
     * @param file      excel
     * @param accountId 区域id
     * @param login     login
     * @return JsonResult
     */
    @Override
    public Result<Object> importFile(MultipartFile file, Integer accountId, LoginInfo login) {
        //解析excel userCodeList-解析出来的车辆编号    failList-失败的车辆编号   addList-新增入库
        List<String> userCodeList = analysisExcel(file);
        List<Object> failList = new ArrayList<>();
        List<UpgradeMachine> addList = new ArrayList<>();
        //获取配置文件版本号 todo
        //查询区域内所有车辆信息 转成map<userCode,machineId>
        Map<String, Integer> map = machineDao.getByAccountId(accountId).stream().collect(Collectors.toMap(Machine::getUserCode, Machine::getMachineId));
        //查询已经导入的车辆，不允许重复导入
        List<String> upgradeMachines = upgradeDao.selectMachineId(accountId);
        for (String useCode : userCodeList) {
            Integer machineId = map.get(useCode);
            if (Objects.isNull(machineId)) {
                log.info("车辆不存在：{}", useCode);
                failList.add(useCode);
                continue;
            }
            if (upgradeMachines.stream().anyMatch(a -> a.equals(machineId.toString()))) {
                log.info("车辆已存在：{}", useCode);
                failList.add(useCode);
                continue;
            }
            addList.add(new UpgradeMachine().setMachineId(machineId).setAccountId(accountId).setCreateTime(new Date()).setCreateUser(login.getId()));
        }
        //新增入库
        saveBatch(addList);
        //构建返回对象
        BatchOperationMsgVO<Object> vo = new BatchOperationMsgVO<>();
        vo.setSuccessList(userCodeList.stream().filter(i -> !failList.contains(i)).collect(Collectors.toList()))
                .setFailList(failList);
        return Result.success(vo);
    }


    /**
     * 导出升级车辆信息
     *
     * @param upgradeDTO upgradeDTO
     * @return excel
     */
    @Override
    public Result<Object> exportFile(UpgradeDTO upgradeDTO) {
        //限制导出数量为60000
        upgradeDTO.setPageNumber(1).setSize(60000);
        PageInfo<UpgradeVO> pageInfo = PageHelper.startPage(upgradeDTO.getPageNumber(), upgradeDTO.getSize()).doSelectPageInfo(() -> upgradeDao.queryPage(upgradeDTO));
        ExcelUtil<UpgradeVO> excelUtil = new ExcelUtil<>(UpgradeVO.class);
        JsonResult result = excelUtil.exportExcel(pageInfo.getList(), "升级车辆列表");
        return Result.success(result.getData());
    }

    /**
     * 删除车辆
     *
     * @param upgradeId 车辆id
     */
    @Override
    public void deleteId(Integer upgradeId) {
        upgradeDao.deleteById(upgradeId);
    }

    /**
     * 升级车辆详情
     *
     * @param upgradeId 升级车辆id
     * @return result
     */
    @Override
    public Result<PageResult<UpgradeDetail>> detail(Integer upgradeId, Integer accountId, Integer pageNumber, Integer size) {
        PageInfo<WriteConfigVoice> pageInfo = PageHelper.startPage(pageNumber, size).doSelectPageInfo(() -> voiceTaskDao.getConfig(accountId));
        List<WriteConfigVoice> voiceList = pageInfo.getList();
        //获取设备编号和车辆编号
        UpgradeDetailVO vos = upgradeDao.selectByUogradeId(upgradeId);
        //查询语音升级日志
        QueryWrapper<VoiceLog> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("machineNo", vos.getMachineNo()).eq("version", voiceList.get(0).getVersion());
        VoiceLog voiceLog = voiceLogDao.selectOne(queryWrapper);
        if (Objects.nonNull(voiceLog)){
            //解析升级结果
            char[] chars = voiceLog.getResStatus().toCharArray();
            int i = 0;
            List<UpgradeDetail> list = new ArrayList<>();
            for (WriteConfigVoice writeConfigVoice : voiceList) {
                UpgradeDetail upgradeDetail = new UpgradeDetail();
                upgradeDetail.setMachineNo(vos.getMachineNo())
                        .setUserCode(vos.getUserCode())
                        .setVersion(writeConfigVoice.getVersion())
                        .setVoiceName(writeConfigVoice.getVoiceName())
                        .setVoiceTaskName(writeConfigVoice.getVoiceTaskName())
                        .setCreateTime(voiceLog.getCreateTime())
                        .setType("0".equals(String.valueOf(chars[i])) ? "升级失败" : "升级成功");
                i++;
                list.add(upgradeDetail);
            }
            return Result.success(new PageResult<>(pageNumber, size, pageInfo.getTotal(), pageInfo.getPages(), list));
        }
       return Result.success();
    }


    /**
     * 解析excel
     *
     * @param file excel
     * @return userCodeList
     */
    private List<String> analysisExcel(MultipartFile file) {
        List<String> userCodeList = new ArrayList<>();
        Workbook workbook;
        try {
            workbook = WorkbookFactory.create(Objects.requireNonNull(AdaPayUtil.MultipartFileToFile(file)));
            Sheet sheet = workbook.getSheetAt(0);
            Integer userCodeIndex = null;
            boolean flag = true;
            for (Row row : sheet) {
                if (flag) {
                    //第一行为标题
                    Iterator<Cell> cellIterator = row.cellIterator();
                    while (cellIterator.hasNext()) {
                        Cell cell = cellIterator.next();
                        if ("车辆编号".equals(cell.getStringCellValue())) {
                            userCodeIndex = cell.getColumnIndex();
                        }
                    }
                    if (userCodeIndex == null) {
                        throw new BaseException("excel文件错误");
                    }
                    flag = false;
                    continue;
                }
                //设置excel单元格类型
                row.getCell(userCodeIndex).setCellType(CellType.STRING);
                userCodeList.add(row.getCell(userCodeIndex).toString());
            }
        } catch (Exception e) {
            log.error("解析excel失败", e);
        }
        //去重
        if (CollectionUtil.isNotEmpty(userCodeList)) {
            userCodeList = userCodeList.stream().distinct().collect(Collectors.toList());
        }
        return userCodeList;
    }
}
